#pragma once
#ifndef _FEM_TRIANGLEFEM_
#define _FEM_TRIANGLEFEM_

//================================================================================================================================
//================================================================================================================================
// QtCore
#include <QtCore/QVector>
// Локальные
#include "linal/vector.h"
#include "geometry/2d/point.h"
#include "geometry/2d/segment.h"
#include "fem/trianglenet.h"
#include "core_global.h"

//================================================================================================================================
//================================================================================================================================
namespace fem
{
    /// Набор утилит для помогающих в работе с МКЭ на треугольниках.
    namespace triangles
    {
        /// Поиск максимума функции.
        //
        /// Для МКЭ на треугольниках максимум решения всегда будет находиться в узле сетки. В случае, если
        /// максимум достигается сразу в нескольких точках расчетной области, функция вернет индекс только
        /// первой встретившейся точки.
        /// \return Индекс точки расчетной области, в которой решение достигает своего максимума.
        CORE_EXPORT int maximum(const linal::Vector &f);

        /// Поиск минимума функции.
        //
        /// Для МКЭ на треугольниках минимум решения всегда будет находиться в узле сетки. В случае, если
        /// минимум достигается сразу в нескольких точках расчетной области, функция вернет индекс только
        /// первой встретившейся точки.
        /// \return Индекс точки расчетной области, в которой решение достигает своего минимума.
        CORE_EXPORT int minimum(const linal::Vector &f);

        /// Поиск максимума функции.
        //
        /// Для МКЭ на треугольниках максимум решения всегда будет находиться в узле сетки. В случае, если
        /// максимум достигается сразу в нескольких точках расчетной области, функция вернет индекс только
        /// первой встретившейся точки.
        /// \return Координаты точки расчетной области, в которой решение достигает своего максимума.
        CORE_EXPORT geometry::_2d::Point maximum(const TriangleNet &net, const linal::Vector& f);

        /// Поиск минимума функции.
        //
        /// Для МКЭ на треугольниках минимум решения всегда будет находиться в узле сетки. В случае, если
        /// минимум достигается сразу в нескольких точках расчетной области, функция вернет индекс только
        /// первой встретившейся точки.
        /// \return Координаты точки расчетной области, в которой решение достигает своего минимума.
        CORE_EXPORT geometry::_2d::Point minimum(const TriangleNet &net, const linal::Vector& f);

        /// Формирование профиля матрицы конечноэлементной СЛАУ в CSR формате.
        /// \param net Конечноэлементная сетка.
        /// \param[out] ig Количество ненулевых элементов в каждой строке матрицы.
        /// \param[out] jg Номера столбцов ненулевых элементов матрицы.
        /// \sa linal::CSRMatrix
        CORE_EXPORT void formMatrixProfile(const TriangleNet &net, QVector<int> &ig, QVector<int> &jg, QVector<int> &ig2, QVector<int> &jg2);

        /// Получение списка отрезков, образующих при соединении изолинию со значением функции равным value.
        CORE_EXPORT QList<geometry::_2d::Segment> isoline(const TriangleNet &net, const linal::Vector &f, double value);

        /// Вычисление значения функции в произвольной точке конечного элемента.
        /// \param triangle Номер конечного элемента, которому принадлежит точка, в которой нужно найти значение функции.
        /// \param net Конечноэлементная сетка.
        /// \param f Функция, значение которой нужно найти в заданной точке.
        /// \param point Точка в которой нужно найти значение функции.
        CORE_EXPORT double functionValue(int triangle, const TriangleNet &net, const linal::Vector &f, const geometry::_2d::Point &point);
    }
}

#endif // _FEM_TRIANGLEFEM_
